﻿using MahApps.Metro.Controls;
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using Microsoft.Win32;
using System.Windows.Controls.Primitives;

using KELT_v5;
using KETL_v5.Viewport;
using System.Windows.Media.Media3D;
using KELT_v5.KELTObjects;
using KELT_v5.KELTObjects.LibraryObjectModel;
using KELT_v5.KELTObjects.ViewportObjectModel;
using KELT_v5.Files;
using KELT_v5.ErrorControl;
using KELT_v5.ErrorControl.CustomException;
using KETL_v5.Animation.Animation2D;
using KETL_v5.Animation.AnimationEffect;
using KETL_v5.Animation.Animation3D;

namespace KETL_v5
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : MetroWindow
    {
        private ObjManager objmgr;           // 오브젝트 매니저

        private OpenFileDialog dlg_text;    // 텍스트 다이얼로그
        private OpenFileDialog dlg_sound;   // 사운드 다이얼로그
        private OpenFileDialog dlg_image;   // 이미지 다이얼로그

        public CameraManager cameraManager; // 카메라 매니저

        
        //MainWindow.xaml 로 이동 - 민수
        public ViewPortMgr viewPortMgr; // viewportobj 매니저

        // 다중 문서 작업을 지원하지 않음으로 최상단에 KELTFile을 하나 둠.
        public FileKELT currentKELTFile = null;
        public KELTFileControl keltFileControl = new KELTFileControl();

        Popup pop;


        public MainWindow()
        {
            InitializeComponent();
            init();

            if(currentKELTFile == null)
            {
                // KELT 파일 이 없을 시 새로 프로젝트 만드는 창 띄울 것
                currentKELTFile = keltFileControl.makeProject(this, new FileKELT());
                // 나중에 이거 코드 새 프로젝트 다이얼로그로 옮길 것.
            }
            else
            {
                // KELT 파일을 로딩 할 것.

            }
           
        }

        public void init()
        {
            this.Loaded += MainWindow_Loaded;

            // window position
            this.Top = 0;
            this.Left = 0;

            // object manager 할당
            objmgr = (ObjManager)Application.Current.FindResource("ObjectManager");

            viewPortMgr = (ViewPortMgr)Application.Current.FindResource("ViewportMgr");
            viewPortMgr.SetMainContext(this);

            cameraManager = (CameraManager)Application.Current.FindResource("CameraManager");
            cameraManager.init(this);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            if (this.IsVisible)
            {
                this.slider_imagesize.Maximum = 250;
                this.slider_imagesize.Minimum = 20;
                this.slider_imagesize.Value = 250;
            }


        }

        private void ToggleFlyout(int p)
        {
            var flyout = this.Flyouts.Items[p] as Flyout;
            if (flyout == null)
            {
                return;
            }

            flyout.IsOpen = !flyout.IsOpen;
        }


        #region 희유-마우스이벤트
        /******** 객체 마우스이벤트 **********************************/
        public void Object_MouseDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                //Mouse.OverrideCursor = Cursors.Hand;
                viewPortMgr.MouseDownObject(sender, e);
                cameraManager.MouseDownObject(sender, e);

            }
            catch
            {

            }
        }
        
        public void Object_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                viewPortMgr.MouseMoveObject();
                cameraManager.MouseMoveObject();
            }
            catch
            {

            }
        }

        /******** 마우스휠이벤트 **********************************/
        private void MouseWheelEventHandler(object sender, MouseWheelEventArgs e)
        {
            cameraManager.CameraZoom(e.Delta);
        }

        /******** 마우스다운이벤트 **********************************/
        private void MouseDownEventHandler(object sender, MouseButtonEventArgs e)
        {
            double x = e.MouseDevice.GetPosition(mainViewport).X;
            double y = e.MouseDevice.GetPosition(mainViewport).Y;


            if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Pressed)
            {
                cameraManager.MouseWheelDown(e.MouseDevice.GetPosition(mainViewport));
            }

        }

        /******** 마우스무브이벤트 **********************************/
        private void MouseMoveEventHandler(object sender, MouseEventArgs e)
        {
            try
            {
                cameraManager.MouseWheelMove(e.MouseDevice.GetPosition(mainViewport));
                viewPortMgr.ObjectRotate();
                viewPortMgr.ObjectScale();
            }
            catch
            {
            }
        }

        /******** 마우스업이벤트 **********************************/
        private void MouseUpEventHandler(object sender, MouseButtonEventArgs e)
        {
            try
            {
                //viewPortMgr.CreateParticleObject("바다로 가자, 바다로 가자.\n갈매기 오라 손짓하는 바다로 가자.\n\n푸른 물결 속에 첨벙 뛰어들어\n물고기처럼 헤엄치다,.", e.MouseDevice.GetPosition(mainViewport).X, e.MouseDevice.GetPosition(mainViewport).Y, 0.0, 0.0 + 20, 0, 0, 0);
                cameraManager.MouseWheelUp(e.MouseDevice.GetPosition(mainViewport));
                viewPortMgr.MouseUpObject();
                cameraManager.MouseUpObject();
                
            }catch
            {

            }
        }

        private void MouseLeaveEventHandler(object sender, MouseEventArgs e)
        {
            try
            {
                cameraManager.MouseWheelUp(e.MouseDevice.GetPosition(mainViewport));
                viewPortMgr.MouseUpObject();
                cameraManager.MouseUpObject();

            }
            catch
            {

            }

        }

        #endregion
        

        #region BTN
        private void btn_save_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 일단 다른이름으로 저장하기 버튼이 아님으로 SaveAs 는 false 로 지정
                keltFileControl.SaveKELT(currentKELTFile, false);
            }
            catch (Exception exception)
            {
                ErrorManager.Instance.RecordError(exception);
            }
        }

        private void btn_image_Click(object sender, RoutedEventArgs e)
        {
            ToggleFlyout(0);
        }

        private void btn_sound_Click(object sender, RoutedEventArgs e)
        {
            ToggleFlyout(1);
        }

        private void btn_text_Click(object sender, RoutedEventArgs e)
        {
            ToggleFlyout(2);
        }

        private void btn_imageload_Click(object sender, RoutedEventArgs e)
        {
            // 이미지 로드 버튼
            dlg_image = new OpenFileDialog();

            dlg_image.Multiselect = true;
            dlg_image.Filter = "image file(*.png) | *.png";
            dlg_image.DefaultExt = "png";
            dlg_image.Title = "Please select a image file.";
            bool? res = dlg_image.ShowDialog();

            if (res.HasValue && res.Value)
            {
                foreach (string str in dlg_image.FileNames)
                {
                    KELT_OBJ obj = new ImageObj();

                    if (obj is ImageObj)
                    {
                        objmgr.CreateImageObj(str, obj, 0, 0, 0, 0, 0, 0, "none");
                    }
                }
            }
        }

        private void btn_soundload_Click(object sender, RoutedEventArgs e)
        {
            // 사운드 로드 버튼
            dlg_sound = new OpenFileDialog();

            dlg_sound.Multiselect = true;
            dlg_sound.Filter = "sound file(*.mp3) | *.mp3";
            dlg_sound.DefaultExt = "mp3";
            dlg_sound.Title = "Please select a sound file.";
            bool? res = dlg_sound.ShowDialog();

            if (res.HasValue && res.Value)
            {
                foreach (string str in dlg_sound.FileNames)
                {
                    KELT_OBJ obj = new SoundObj();

                    if (obj is SoundObj)
                    {
                        objmgr.CreateSoundObj(str, obj, 0, 0, 0, 0, 0, 0, "none");
                    }
                }

            }
        }

        private void btn_textload_Click(object sender, RoutedEventArgs e)
        {
            // 텍스트 로드 버튼
            dlg_text = new OpenFileDialog();

            dlg_text.Multiselect = true;
            dlg_text.Filter = "text file(*.txt) | *.txt";
            dlg_text.DefaultExt = "txt";
            dlg_text.Title = "Text Files to choose from.";
            bool? res = dlg_text.ShowDialog();

            if (res.HasValue && res.Value)
            {
                foreach (string str in dlg_text.FileNames)
                {
                    using (StreamReader sr = new StreamReader(str, System.Text.Encoding.Default))
                    {
                        this.txtbox_text.Text += sr.ReadToEnd();
                        this.txtbox_text.Text += '\n';
                    }
                }

            }
        }

        private void btn_textdone_Click(object sender, RoutedEventArgs e)
        {
            // 텍스트 편집 완료 버튼
            string str = this.txtbox_text.Text;
            string[] words = str.Split(' ');
            foreach (string text in words)
            {
                string[] word2 = text.Split('\r');
                foreach (string text2 in word2)
                {
                    string[] word3 = text2.Split('\n');
                    foreach (string text3 in word3)
                    {
                        if (text3 != "")
                        {
                            // 띄어쓰기, 개행 모두 제거한 객체
                            KELT_OBJ textobj = new TextObj();
                            objmgr.CreateTextObj("직접입력", textobj, text3, 10, 0, 0, 0, 0, 0, "none");
                        }
                    }
                }
            }
        }

        private void btn_camera_Click(object sender, RoutedEventArgs e)
        {

        }

        private void btn_zoomin_Click(object sender, RoutedEventArgs e)
        {
            cameraManager.CameraZoomOut();

        }

        private void btn_zoomout_Click(object sender, RoutedEventArgs e)
        {
            cameraManager.CameraZoomIn();

        }
        #endregion

        private void slider_imagesize_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            foreach (ImageObj img in listbox_image.Items)
            {
                img.ScaledHeight = (int)slider_imagesize.Value;
                img.ScaledWidth = (int)slider_imagesize.Value;
            }
        }

        #region Mouse
        private void loadimage_MouseEnter(object sender, MouseEventArgs e)
        {
            this.listbox_image.SelectedItem = (sender as Image).DataContext;
            KELT_OBJ obj = (KELT_OBJ)this.listbox_image.SelectedItem;
            //this.ttip_text = obj.FileName;
            this.ttip_text.Text = ((ImageObj)obj).fileName;
        }
        
        private void MetroWindow_Selected(object sender, RoutedEventArgs e)
        {

        }

        private void MetroWindow_MouseMove(object sender, MouseEventArgs e)
        {
            //double pt = (double)(e.GetPosition(this));
            //this.ttip_imagelist.HorizontalOffset = Convert.ToDouble(pt);
            //this.ttip_imagelist.VerticalOffset = Convert.ToDouble(pt);
        }

        private void loadimage_MouseMove(object sender, MouseEventArgs e)
        {
            this.ttip_imagelist.Margin = new Thickness(e.GetPosition(this).X, e.GetPosition(this).Y, 0, 0);
        }

        private void listbox_text_up(object sender, MouseButtonEventArgs e)
        {
            objmgr.SelectObject(listbox_text.SelectedItems);
        }

        private void listbox_image_MouseUp(object sender, MouseButtonEventArgs e)
        {
            objmgr.SelectObject(listbox_image.SelectedItems);
        }

        #endregion

        #region Keyboard
        private void KeyboardHandler(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                this.listbox_text.UnselectAll();
                objmgr.ClearSelectList();
                viewPortMgr.unSelectObject();
            }
            else if (e.Key == Key.Delete)
            {
                
                viewPortMgr.DeleteObject();
            }
            
        }
        #endregion

        #region DragAndDrop
        private void ListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ListBox parent = (ListBox)sender;
            ListBox dragSource = parent;
            object data = GetDataFromListBox(dragSource, e.GetPosition(parent));

            if (data != null)
            {
                DragDrop.DoDragDrop(parent, data, DragDropEffects.Move);
            }
            if (Keyboard.IsKeyDown(Key.LeftCtrl) == false)
            {
                objmgr.ClearSelectList();
            }
            objmgr.SelectObject(listbox_text.SelectedItems);
        }


        private static object GetDataFromListBox(ListBox source, Point point)
        {
            UIElement element = source.InputHitTest(point) as UIElement;
            if (element != null)
            {
                object data = DependencyProperty.UnsetValue;
                while (data == DependencyProperty.UnsetValue)
                {
                    data = source.ItemContainerGenerator.ItemFromContainer(element);
                    if (data == DependencyProperty.UnsetValue)
                    {
                        element = VisualTreeHelper.GetParent(element) as UIElement;
                    }
                    if (element == source)
                    {
                        return null;
                    }
                }
                if (data != DependencyProperty.UnsetValue)
                {
                    return data;
                }
            }
            return null;
        }


        //3D Viewport Drop Event
        private void ListBox_Drop(object sender, DragEventArgs e)
        {
            object data = e.Data.GetData(typeof(TextObj));
            if (data == null) data = e.Data.GetData(typeof(ImageObj));
            if (data == null) data = e.Data.GetData(typeof(SoundObj));

            Point p = e.GetPosition(this);
            string dataType = (data as KELT_OBJ).objectType;

            if (objmgr.selectList.Count <= 1)
            {
                if (dataType == "TextObj")
                {
                   viewPortMgr.CreateText(((TextObj)data), p.X, p.Y - 130, 0, 0 + 3, 1, 0, 0, 3);
                }
                else if (dataType == "ImageObj")
                {
                    viewPortMgr.createPictureObject(((ImageObj)data), p.X, p.Y - 130, 0, 0 + 3);
                }
                viewPortMgr.selectList.Clear();
            }
            else
            {
                Random rand = new Random();
                byte[] colorBytes = new byte[3];
                viewPortMgr.CreateGroupText(objmgr.selectList, p.X, p.Y-130, 0, 3, 1, 0, 0, 0);
                
            }
        }
        #endregion


        #region AnimationButton
        //나타나기 애니메이션
        private void btn_aniappear_Click(object sender, RoutedEventArgs e)
        {
            viewPortMgr.ObjectAnimationRegist(new OpacityApearAnimation());
            
        }

        //날아오기 애니메이션
        private void btn_aniflyappear_Click(object sender, RoutedEventArgs e)
        {
            FlyAppearAnimation flyAppear = new FlyAppearAnimation();
            flyAppear.setOption(0);
            viewPortMgr.ObjectAnimationRegist(flyAppear);
        }

        //날아가기 애니메이션
        private void btn_aniupappear_Click(object sender, RoutedEventArgs e)
        {
            FlyAppearAnimation flyAppear = new FlyAppearAnimation();
            flyAppear.setOption(2);
            viewPortMgr.ObjectAnimationRegist(flyAppear);

        }

        //바운스 애니메이션
        private void btn_anibounceappear_Click(object sender, RoutedEventArgs e)
        {
            BounceAnimation bounce = new BounceAnimation();
            viewPortMgr.ObjectAnimationRegist(bounce);

        }

        //사라지기 애니메이션
        private void btn_anidisappear_Click(object sender, RoutedEventArgs e)
        {
            viewPortMgr.ObjectAnimationRegist(new OpacityDisappearAnimation());

        }

        //사라지기 애니메이션
        private void btn_anibrightout_Click(object sender, RoutedEventArgs e)
        {
            viewPortMgr.ObjectAnimationRegist(new OpacityDisappearAnimation());

        }

        //날아가기 애니메이션
        private void btn_flyout_Click(object sender, RoutedEventArgs e)
        {
            FlyDisAppearAnimation flyAppear2 = new FlyDisAppearAnimation();
            flyAppear2.setOption(1);
            viewPortMgr.ObjectAnimationRegist(flyAppear2);

        }

        //떨어지기 애니메이션
        private void btn_anifall_Click(object sender, RoutedEventArgs e)
        {

            FlyDisAppearAnimation flyAppear2 = new FlyDisAppearAnimation();
            flyAppear2.setOption(3);
            viewPortMgr.ObjectAnimationRegist(flyAppear2);
        }

        //바운스 애니메이션
        private void btn_bounceout_Click(object sender, RoutedEventArgs e)
        {
            BounceAnimation bounce = new BounceAnimation();
            viewPortMgr.ObjectAnimationRegist(bounce);

        }

        //색상 애니메이션
        private void btn_colorAni_Click(object sender, RoutedEventArgs e)
        {
            ColorAni color = new ColorAni();
            viewPortMgr.ObjectAnimationRegist(color);

        }

        //깜박이기 애니메이션
        private void btn_pulse_Click(object sender, RoutedEventArgs e)
        {
            PulseAnimation pulse = new PulseAnimation();
            viewPortMgr.ObjectAnimationRegist(pulse);

        }

        //확대/축소 애니메이션
        private void btn_resize_Click(object sender, RoutedEventArgs e)
        {
            ZoomAnimation zoom = new ZoomAnimation();
            zoom.setOption(1, 2.5);
            viewPortMgr.ObjectAnimationRegist(zoom);
        }

        //2D 회전 애니메이션
        private void btn_rotate_Click(object sender, RoutedEventArgs e)
        {
            Rot2DAnimation rotate2D = new Rot2DAnimation();
            viewPortMgr.ObjectAnimationRegist(rotate2D);

        }

        //흔들기 애니메이션
        private void btn_shake_Click(object sender, RoutedEventArgs e)
        {
            ShakeAnimation qu = new ShakeAnimation();
            qu.setOption(20);
            viewPortMgr.ObjectAnimationRegist(qu);

        }

        //마스크 애니메이션
        private void btn_mask_Click(object sender, RoutedEventArgs e)
        {
            MaskAnimation mask = new MaskAnimation();
            viewPortMgr.changeOpacityMask();
            viewPortMgr.ObjectAnimationRegist(mask);

        }

        //3D 회전 애니메이션
        private void btn_3drotate_Click(object sender, RoutedEventArgs e)
        {
            Rot3DAnimation rotate3D = new Rot3DAnimation();
            rotate3D.setOption(1);
            viewPortMgr.ObjectAnimationRegist(rotate3D);
        }
        #endregion


        #region AnimationControlButton
        //*******************애니메이션 컨트롤 버튼*****************************/
        private void btn_play_Click(object sender, RoutedEventArgs e)
        {
            viewPortMgr.Sart();
            cameraManager.Sart();

        }
        private void btn_stop_Click(object sender, RoutedEventArgs e)
        {
            viewPortMgr.Stop();
            cameraManager.Stop();
        }
        #endregion
        private void btn_colorPicker_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.ColorDialog colorDlg = new System.Windows.Forms.ColorDialog();

            ColorPickerWindow pickerWindow = new ColorPickerWindow(this);
            pickerWindow.Show();

        }


    }
}
